package com.lxb.myforum.security.filter;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.security.web.WebAttributes;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.util.Assert;
import org.springframework.web.filter.GenericFilterBean;

import com.lxb.myforum.security.exception.CaptchaException;

/**
 * 
 * @author lxb
 *
 */
public class LoginVerifyCodeFilter extends GenericFilterBean {
	private static final String VERIFY_CODE_PARAMETER = "verifyCode";
	private RequestMatcher requiresAuthenticationRequestMatcher;
	
	private final Log logger = LogFactory.getLog(getClass());
	
	@Override
	public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
			throws IOException, ServletException {
		logger.debug("[" +getFilterName() + "]");
		logger.info("[" +getFilterName() + "]");
		HttpServletRequest request = (HttpServletRequest) req;
		HttpServletResponse response = (HttpServletResponse) res;
		
		if (!requiresAuthentication(request, response)) {
			chain.doFilter(request, response);
			return;
		}
		
		// 验证验证码
		String vc = request.getParameter(VERIFY_CODE_PARAMETER);
		String verifyCode = (String) request.getSession().getAttribute("VERIFY_CODE");
		if(!StringUtils.equals(vc, verifyCode)) {
			request.setAttribute(WebAttributes.AUTHENTICATION_EXCEPTION, new CaptchaException("验证码错误"));
			logger.debug("[" +getFilterName() + "]  验证码错误");
			logger.info("[" +getFilterName() + "]  验证码错误");
			request.getRequestDispatcher("/loginFail").forward(request, response);
			return;
		}
		logger.debug("[" +getFilterName() + "]  验证码: " + vc + ", " + verifyCode);
		logger.info("[" +getFilterName() + "]  验证码: " + vc + ", " + verifyCode);
		chain.doFilter(request, response);
	}
	
	public LoginVerifyCodeFilter() {
		this(new AntPathRequestMatcher("/login", "POST"));
	}
	
	public LoginVerifyCodeFilter(RequestMatcher requiresAuthenticationRequestMatcher) {
		Assert.notNull(requiresAuthenticationRequestMatcher,
				"requiresAuthenticationRequestMatcher cannot be null");
		this.requiresAuthenticationRequestMatcher = requiresAuthenticationRequestMatcher;
	}
	
	protected boolean requiresAuthentication(HttpServletRequest request,
			HttpServletResponse response) {
		return requiresAuthenticationRequestMatcher.matches(request);
	}
}
